package com.linjiahao.netty.handler;

import com.alibaba.fastjson.JSON;
import com.linjiahao.netty.server.RedisService;
import com.linjiahao.netty.util.JWTUtil;
import com.linjiahao.netty.constant.ErrorMessage;
import io.netty.channel.*;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * @ClassName WebSocketAuthHttpHanlder
 * @Description: 鉴权
 * @Author linjiahao
 * @Date 23/12/2021
 **/
@Component
@Slf4j
public class WebSocketAuthHttpHanlder {

    private WebSocketServerHandshaker handshaker;

    @Autowired
    private RedisService redisService;

    @Value("${netty.url}")
    private String webSocketUrl;

    public final String token = "token";

    public void authHandler(ChannelHandlerContext ctx, FullHttpRequest message) {
        String uri = message.uri();
        log.info("连接前鉴权的uri:{}",uri);
        List<String> list = Arrays.asList(uri.split("\\?"));
        List<String> params = Arrays.asList(list.get(1).split("&"));
        String authToken = params.stream().filter(m -> m.contains(token)).findFirst().get();
        if(StringUtils.isBlank(authToken)){
            httpResponseResult(1,ctx.channel());
            return;
        }
        String tokenValue = authToken.split("=")[1];
        String userId = JWTUtil.getUserId(tokenValue);
        if(!JWTUtil.verify(tokenValue)){
            redisService.hdel(ChannelHandlerPool.channelUserKey,userId);
            httpResponseResult(2,ctx.channel());
            return;
        }
        log.info("channel的id为：{},用户id为：{}",ctx.channel().id(),userId);
        redisService.hset(ChannelHandlerPool.channelUserKey, userId, ctx.channel().id());
        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                webSocketUrl, "WebSocket", false,65536 * 10);
        handshaker = wsFactory.newHandshaker(message);
        if (handshaker == null) {
            WebSocketServerHandshakerFactory
                    .sendUnsupportedVersionResponse(ctx.channel());
        } else {
            handshaker.handshake(ctx.channel(), message);
        }
    }


    private void httpResponseResult(Integer code, Channel channel){
        switch (code){
            case 1:
                channel.writeAndFlush(JSON.toJSONString(ErrorMessage.USER_NOT_LOGIN));
                channel.close();
                break;
            case 2:
                channel.writeAndFlush(JSON.toJSONString(ErrorMessage.TOKEN_IS_NOT_VALIDATE));
                channel.close();
                break;
            default:
                channel.writeAndFlush(JSON.toJSONString(ErrorMessage.SYSTEM_EXCEPTION));
                channel.close();
        }

    }

}
